#!/usr/bin/ruby
$: << File.join(File.expand_path(File.dirname(__FILE__)), "..")
require 'rubygems'
require 'optparse'
require 'csv'
require 'EasyHadoop'

#==================================
# Lookup.rb
# Uses lookup file to build a hash map and replaces hash keys in input line with hash value
# lookfile has to be in the following format: 
# 	key1\tvalue
#   key2\t value
#==================================

class Lookup < EasyHadoop
	
	attr_reader :options, :optparse, :db, :max_index
	
	#constructor
	def initialize(arguments=nil)
		super(arguments)
		loadDB
	end
	
	#Load lookup file into memory
	def loadDB(options=nil)
		@db = {}
		CSV.open(@options[:lookup_path],'r',
				 	@options[:lookup_delimiter]){|row|
				next if row.nil? or row.length < 2
				key = row[0].to_s.strip
				@db[key]=[] unless @db.has_key?(key)
				@db[key] << row[1..row.length-1].join('|')
		}
		@max_index = @options[:lookup_column].sort.last
		puts "DB size: #{@db.length}" if @options[:debug]
		puts "DB Sample row: #{@db.first.inspect}" if @options[:debug]
	end
	
	def set_mandatory
		super
		@mandatory << :lookup_path
		@mandatory << :lookup_delimiter
		@mandatory << :lookup_column
	end

	#define arguments
	def set_commands
		super
		@optparse.banner = "Usage: ruby #{__FILE__} --lookup_path=PATH --lookup_delimiter DELM --lookup_column=NUM --input_delimiter DELM"
			
		@options[:lookup_path]=nil
		@optparse.on('--lookup-path=PATH', 'Path to the lookup file') do |path|
				raise OptionParser::InvalidOption, "Unable to find file at #{path}" unless File.exists?(path)
				@options[:lookup_path] = path
		end

		@options[:lookup_delimiter] = nil
		@optparse.on('--lookup-delimiter=DELM', 'Delimiter for lookup file') do |delm|
				@options[:lookup_delimiter]=OptionParserUtil.handle_delimiter(delm, "\t")
		end	
		
		@options[:lookup_column]=nil
		@optparse.on('--lookup-column=LIST','column index containing lookup values in the input') do |index|
				@options[:lookup_column] = OptionParserUtil.parse_int_array(index)
		end
	end	
	
	#Required method
	#execute/handle line
	def execute(line)
		return line if line.nil? or line.strip.length == 0
		tokens = line.to_s.chomp.strip.split(@options[:input_delimiter])
		@options[:lookup_column].each{|col|
        	next if col > tokens.length-1
        	key = tokens[col]
        	tokens[col] = @db[key].join('|') if @db.has_key?(key)
        }
        return tokens.join(@options[:output_delimiter])
	end
end

# Scripting Option
if __FILE__ == $0
    cls = Lookup.new(ARGV)
    STDIN.each_line{|line|
	  value = cls.execute(line) 
	  puts value
    }
end
